#include "Grid.h"
#include <GL/glut.h>
#include <iostream>
using namespace std;

// Used in keeping a global texture counter
extern unsigned int texture_counter;

////////////////////////////////////////////////////
////////////////////////////////////////////////////
bool GridSquare::placeDoodle(C3DModel model, float dimension)
{
	if(has_doodle)
		return 0;
	doodle=model;
	has_doodle=true;
	BoundingBox tempBox = doodle.getBBox();
	if(abs(tempBox.max.x-tempBox.min.x)>=abs(tempBox.max.y-tempBox.min.y))
		mesh_scale=dimension/abs((tempBox.max.x-tempBox.min.x));
	else
		mesh_scale=dimension/abs((tempBox.max.y-tempBox.min.y));
	height= abs(tempBox.max.z-tempBox.min.z);
	return 1;
}

C3DModel GridSquare::getDoodle(void)
{
	if(!has_doodle)
		return 0;
	return doodle;
}

void GridSquare::drawDoodle(void)
{
	if(!has_doodle)
		return;
	glPushMatrix();
	glScalef(mesh_scale,mesh_scale,mesh_scale);
	glRotatef(rotation,0,0,1);
	glTranslatef(0,0,height/2);
	doodle.drawMesh();
	//doodle.drawBBox();
	glPopMatrix();
}

GridSquare::~GridSquare()
{
	if(has_doodle)
		doodle.~C3DModel();
}

//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

void Grid::initialize(unsigned int x_sqrs, unsigned int y_sqrs, float x_pos, float y_pos, float z_pos, float sqr_length)
{
	x_squares=x_sqrs;
	y_squares=y_sqrs;
	position.x=x_pos;
	position.y=y_pos;
	position.z=z_pos;
	square_length=sqr_length;
	grid = new GridSquare*[x_squares];
	for(int i=0; i<(x_squares);i++)
		grid[i]=new GridSquare[y_squares];
}

void Grid::drawGrid(void)
{
	glPushMatrix();
	glTranslatef(position.x,position.y,position.z);
	if(textured)
		glBindTexture(GL_TEXTURE_2D, grid_texture.ID);
	for(int i=0;i<x_squares;i++)
		for(int h=0;h<y_squares;h++)
		{
			glColor3f(1,1,1); // CUD
			glBegin(GL_QUADS);
				if(textured)
					glTexCoord2f((float)i/x_squares, (float)h/y_squares);
				glVertex2f(i*square_length,h*square_length);
				if(textured)
					glTexCoord2f((float)i/x_squares, ((float)h+1)/y_squares);
				glVertex2f(i*square_length,(h+1)*square_length);
				if(textured)
					glTexCoord2f((float)(i+1)/x_squares, (float)(h+1)/y_squares);
				glVertex2f((i+1)*square_length,(h+1)*square_length);
				if(textured)
					glTexCoord2f((float)(i+1)/x_squares, (float)h/y_squares);
				glVertex2f((i+1)*square_length,h*square_length);
			glEnd();
		}
	if(textured)
		glBindTexture(GL_TEXTURE_2D, 0);
	for(int i=0;i<x_squares;i++)
		for(int h=0;h<y_squares;h++)
		{
			if(grid[i][h].hasDoodle())
			{
				glPushMatrix();
				glTranslatef((i+0.5)*square_length,(h+0.5)*square_length,0);
				grid[i][h].drawDoodle();
				glPopMatrix();
			}
		}
	glPopMatrix();
}

void Grid::addDoodle(unsigned x, unsigned y, C3DModel model, float dimension)
{
	grid[x][y].placeDoodle(model,dimension);
}

bool Grid::moveDoodle(unsigned x1, unsigned y1, unsigned x2, unsigned y2)
{
	if(grid[x1][y1].hasDoodle() && !grid[x2][y2].hasDoodle())
	{
		grid[x2][y2].placeDoodle(grid[x1][y1].getDoodle());
		grid[x1][y1].clearDoodle();
		
		return 1;
	}
	else
		return 0;
}

bool Grid::setTexture(char * file)
{
	if(!grid_texture.LoadTGA(file))
		return 0;
	textured=true;
	grid_texture.ID=texture_counter;
	texture_counter++;

	glGenTextures(1,&grid_texture.ID);
   
	glBindTexture(GL_TEXTURE_2D, grid_texture.ID);
	// texture params
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
   
	glTexImage2D(GL_TEXTURE_2D, 0, 3, grid_texture.imageWidth, grid_texture.imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, grid_texture.image);

	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, grid_texture.imageWidth, grid_texture.imageHeight, GL_RGB, GL_UNSIGNED_BYTE, grid_texture.image);
	glBindTexture(GL_TEXTURE_2D, 0);
	return 1;
}

///
// Episode methods
///

void Grid::calculatePaths(int x, int y, int distance)
{

}

Grid::~Grid(){

}

